package com.etl.task.handler;

import com.eksframework.commons.core.base.EksDate;
import com.eksframework.commons.core.constant.ConstString;
import com.etl.constant.ResultField;
import com.etl.es.document.*;
import com.etl.es.repository.OrderRepository;
import com.etl.es.service.ChannelService;
import com.etl.extract.DatabaseBuilder;
import com.etl.extract.ScheduleTask;
import com.etl.extract.SqlQuery;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 订单处理类
 *
 * @author: chenfenghai
 * @version: 1.0
 * @date: 2020-10-30 9:55
 */
@Slf4j
@Component
public class OrderHandler {

    @Autowired
    DatabaseBuilder databaseBuilder;

    @Autowired
    ChannelService channelService;

    @Autowired
    OrderRepository orderRepository;

    @Autowired
    GoodsHandler goodsHandler;

    @Autowired
    FilmTicketHandler filmTicketHandler;

    /**
     * 查询销售订单列表
     *
     * @param scheduleTask 调度任务信息
     * @param parameterMap SQL参数MAP
     * @return List
     */
    public List<Map<String, String>> findSaleBillList(
            ScheduleTask scheduleTask, Map<String, Object> parameterMap) {
        SqlQuery extractQuery = SqlQuery.builder()
                .id("com.etl.task.mapper.SaleOrderMapper.findSaleBillList")
                .parameterObject(parameterMap)
                .build();
        return databaseBuilder.queryData(scheduleTask, extractQuery);
    }

    /**
     * 查询退货订单列表
     *
     * @param scheduleTask 调度任务信息
     * @param parameterMap SQL参数MAP
     * @return List
     */
    public List<Map<String, String>> findRejectBillList(
            ScheduleTask scheduleTask, Map<String, Object> parameterMap) {
        SqlQuery extractQuery = SqlQuery.builder()
                .id("com.etl.task.mapper.RejectOrderMapper.findRejectBillList")
                .parameterObject(parameterMap)
                .build();
        return databaseBuilder.queryData(scheduleTask, extractQuery);
    }

    /**
     * 保存ES订单文档列表
     *
     * @param scheduleTask 调度任务信息
     * @param orderList    查询订单列表
     * @param goodsList    查询商品列表
     * @param planList     查询排期列表
     */
    public void saveOrderDocumentList(ScheduleTask scheduleTask,
                                      List<Map<String, String>> orderList,
                                      List<Map<String, String>> goodsList,
                                      List<Map<String, String>> planList) {
        // 转换为es保存对象
        List<OrderDocument> orderDocumentList = Lists.newArrayList();
        List<GoodsDocument> goodsDocumentList = Lists.newArrayList();
        List<FilmTicketDocument> filmTicketDocumentList = Lists.newArrayList();
        // 转换为es保存对象
        orderList.forEach(obj -> {
            // 订单
            OrderDocument orderDocument = buildOrderDocument(scheduleTask, obj);
            // 商品
            Map<String, String> goodsMap = goodsList.parallelStream().filter(map -> Objects.equals(
                    map.get(ResultField.BILL_CODE), orderDocument.getOrderCode()))
                    .findFirst().orElse(null);
            // 放映计划
            Map<String, String> planMap = planList.parallelStream().filter(map -> Objects.equals(
                    map.get(ResultField.BILL_CODE), orderDocument.getOrderCode()))
                    .findFirst().orElse(null);
            // 添加到集合里
            orderDocumentList.add(orderDocument);
            goodsDocumentList.addAll(goodsHandler.buildGoodsDocumentList(orderDocument, goodsMap));
            filmTicketDocumentList.addAll(filmTicketHandler.buildFilmTicketDocumentList(
                    orderDocument, goodsMap, planMap));
        });
        // 保存
        orderRepository.saveAll(orderDocumentList);
        goodsHandler.saveGoodsDocumentList(goodsDocumentList);
        filmTicketHandler.saveFilmTicketDocumentList(filmTicketDocumentList);
    }

    /**
     * 建造ES订单文档
     *
     * @param scheduleTask 调度任务信息
     * @param orderMap     查询订单结果MAP
     * @return OrderDocument
     */
    public OrderDocument buildOrderDocument(
            ScheduleTask scheduleTask, Map<String, String> orderMap) {
        // 下单时间
        EksDate orderDateTime = EksDate.of(orderMap.get(ResultField.PAYED_TIME));
        // 处理渠道
        ChannelDocument channelDocument = channelService.saveOrReplaceChannelDocument(
                orderMap.get(ResultField.CHANNEL_UID),
                ChannelDocument.builder()
                        .channelCode(orderMap.get(ResultField.CHANNEL_CODE))
                        .channelName(orderMap.get(ResultField.CHANNEL_NAME))
                        .channelTypeCode(Byte.valueOf(orderMap.get(ResultField.CHANNEL_TYPE)))
                        .build());
        return OrderDocument.builder()
                .orderId(StringUtils.joinWith(ConstString.UNDERLINE,
                        scheduleTask.getTenant().getTenantCode(),
                        scheduleTask.getCinema().getCinemaCode(),
                        orderMap.get(ResultField.BILL_CODE)))
                .orderCode(orderMap.get(ResultField.BILL_CODE))
                .tenantCode(scheduleTask.getTenant().getTenantCode())
                .tenantName(scheduleTask.getTenant().getTenantName())
                .cinemaCode(scheduleTask.getCinema().getCinemaCode())
                .cinemaName(scheduleTask.getCinema().getCinemaName())
                .channelCode(channelDocument.getChannelCode())
                .channelName(channelDocument.getChannelName())
                .channelTypeCode(channelDocument.getChannelTypeCode())
                .channelTypeName(channelDocument.getChannelTypeName())
                .orderYear(orderDateTime.toLocalDate().getYear() + EksDate.CN_YEAR)
                .orderMonth(orderDateTime.toString(EksDate.PATTERN_YYYYMM_CN))
                .orderDay(orderDateTime.toString(EksDate.PATTERN_YYYYMMDD_CN))
                .orderHour(orderDateTime.toString(EksDate.PATTERN_YYYYMMDDHH_CN))
                .orderDateTime(orderDateTime.toDate())
                .orderPrice(Double.parseDouble(orderMap.get(ResultField.PAY_PRICE)))
                .build();
    }
}
